 PAG
*********************************
*           SEG2
*********************************

]segnum = #$0200  ;current segment number

 ORG $E0C800  ;CODE RUNS HERE

* This space is shared with the VIA and the RAM.

*************** MESSAGES *************

* The following string is used for displaying register labels.

MSGREGA ASC "A="
 DFB EOT
 ASC " X="
 DFB EOT
 ASC " Y="
 DFB EOT
 ASC " S="
 DFB EOT
 ASC " D="
 DFB EOT
 ASC " B="
 DFB EOT
 ASC "  M="
 DFB EOT
 ASC " Q="
 DFB EOT
 ASC " P="
 DFB EOT
 ASC " L="
 DFB EOT
 ASC " E="
 DFB EOT
 ASC " I="
 DFB EOT


* The following string is used for displaying the status flags.

FLAGS ASC "NV1BDIZC"
FLAGS16 ASC "NVMXDIZC"

**************************************************
* The following routines are run from the cards I/O space.

 MX %11

*----------------------------------------
*   ---- SEG0 ROUTINES ----
* Disable the CXROM from the I/O space before entering DDT slot space
* The user's program is vectored here during interrupts.

IOSTUF0 NOP  ;reserved
 PHP   ;save post interrupt status
 MEMORY8
 PHA   ;save ACC
 LDAL CXFLAG  ;get CXROM status
 STAL SLOTROM  ;turn CXROM off
 JMP SLOTINT  ;goto slot space interrupt handler

*----------------------------------------
*   ---- SEG1 ROUTINES ----
* Part1 of goto user's code or LDA/STA one byte

* Hard coded to slot #3 for now.

IOSTUF1 CMPL $E0CFFF  ;2K ROM off
 CMPL $E0C300  ;activate user's peripheral card
 STAL $E0C008  ;bank switch (08 ORed with n0+80)

*----------------------------------------
*   ---- SEG7 ROUTINES ----
* Part2 of goto user's code

IOSTUF7 NOP
 NOP   ;reserved
 NOP
:TOP7 STAL $E0C007  ;CXROM on or $C006 CXROM off
 LDA #00  ;restore Acc
 RTI   ;goto user's code OR PLP
 JML $FFBC6C  ;goto GS interrupt handler, used by TOGSINT
* Start here
 BRA :TOP7

*----------------------------------------
*   ---- SEG8 ROUTINES ----
* Part2 of LDA or STA one byte
* The bank register remains at $E0 during this code

IOSTUF8
:TOP8 STA $C007  ;activate CXROM or $C006 keep CXROM off
 XBA   ;restore Acc
 nop
 nop
 nop   ;space fillers for LDAL,X or STAL,X
 nop
 STA SLOTROM  ;CXROM off
 JMP SLOTRTS  ;Return to our slot routine
* Start here
 BRA :TOP8


****************************************
*   CAUTION  segement dependent code   *
****************************************

*----------------------------
* Transfer the IO routines to IO space
* Enter with X = slotn0
* Parameters passed on stack
* !!!!! NOTE Stack can NOT be in DDT RAM !!!!!

XFRIO LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X
 LDY #15
:SEG0 LDA IOSTUF0,Y
 STA IOSPACE0,Y
 DEY
 BPL :SEG0
 LDA 3,S  ;get slotCn
 STA IOCN0  ;set for current slot

 LDA #%00010010 ;RAM1, ROM2
 STA SEGMBASE,X
 LDY #11
:SEG1 LDA IOSTUF1,Y
 STA IOSPACE1,Y
 DEY
 BPL :SEG1
 LDA 4,S  ;get slotn0+$80

 ORA IOSTUF1+9 ;set IOSEGM value for current slot
 STA IOSEGM  ;set for current slot
* TSB IOSEGM ;this statement OR the above 2?

 LDA 4,S ;get slotn0+$80
 ORA #IOSPACE1-$80 ;add offset to start of SEG1 code
 STA TOSLOTC0 ;init JMP() vector
 LDA #$C0  ;  to point to I/O routines
 STA TOSLOTC0+1

 LDA #%01110010 ;RAM7, ROM2
 STA SEGMBASE,X
 LDY #15
:SEG7 LDA IOSTUF7,Y
 STA IOSPACE7,Y
 DEY
 BPL :SEG7

 LDA #%10000010 ;RAM8, ROM2
 STA SEGMBASE,X
 LDY #15
:SEG8 LDA IOSTUF8,Y
 STA IOSPACE8,Y
 DEY
 BPL :SEG8
 LDA 3,S  ;get slotCn
 STA IOSPACE8+13 ;set for current slot

 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X
 JMP SEG2RTS  ;jmp to RTS to reenable DDT RAM

*--------------------
MSGMODE EQU *
 DFB CR
 ASC "--- Mode of Operation ---"
 DFB CR,CR

 ASC "Text screen save"
 DFB CR
 ASC "1=on  2=off"
 DFB EOT

 DFB CR
 ASC "CPU"
 DFB CR
 ASC "1=6502  2=65C02  3=65816"
 DFB EOT

 DFB CR
 ASC "I/O slot #"
 DFB CR
 ASC "1:out  2:in/out  3:normal"
 DFB EOT


MSGENTER DFB CR
 ASC "Enter <" ;put current setting in brackets
 DFB EOT
 ASC "> :"
 DFB EOT

* messages for execution time

MSGET EQU *
 ASC "MEGA][ cycles = $"
 DFB EOT

FASTET ASC " (x ~2.6)"
 DFB EOT


****************************************
* THIS POINT MUST BE $CA00 OR ABOVE.
****************************************

 ERR *-1/$E0CA00
 DS $E0CA00-*,$FF

* Replace the original instruction with a BRK command
* Set carry if we have a break there already

PUTBREAK JSR VALIDAD  ;ALREADY HAVE A BRK THERE?,PUT Y IN YBUFF
 BMI PUTBRK2  ;IF NO
 JSR REPLACE  ;IF YES, REMOVE OLD BRK
PUTBRK2 LDA SBTYPE  ;GET SB TYPE
 CMP #"I"  ;IS IT IMPLIED
 BEQ UPDATE  ;IF YES

 MEMORY16
 LDA LETTER1
 STA LOWADD  ;SETUP POINTER
 MEMORY8
 LDA LETTER3
 STA DBRDDT  ;BANK #

 LDY #0
 JSR TRANSFR2 ;READ DATA AT BREAKPOINT ADDRESS
 DFB LDAINDYC ;CODE
 STA DATABRK  ;SAVE ORIG DATA
 TYA   ;LOAD ACC WITH 00
 JSR TRANSFR2 ;STORE BREAK
 DFB STAINDYC ;CODE
 JSR TRANSFR2 ;VERIFY THAT LOCATION WAS RAM, SET Z BIT IF OK
 DFB LDAINDYC ;CODE
 BNE PUTDONE  ;ERROR, "NOT RAM"
 INC REALBRK  ;COUNT REAL BREAKS

* Update the breakpoint list.

UPDATE LDY POINT  ;BRK STACK POINTER
 STX XBUFF  ;SAVE
 LDX #9
:LOOP LDA DATABRK,X ;BRK STACK INFO
 PHA   ;ON SYSTEM STACK
 DEX
 BPL :LOOP

 LDX SLOTN0
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,X
* Pull BRK info off system stack and put in BRK stack
 PLA
 STA BRKDATA,Y
 PLA
 STA BRKLOW,Y
 PLA
 STA BRKHI,Y
 PLA
 STA BRKPBR,Y
 PLA
 STA BRKTGLOW,Y
 STA BRKPASLO,Y
 PLA
 STA BRKTGHI,Y
 STA BRKPASHI,Y

 LDA 4,S ; get BRK type
 CMP #"C" ; is this Conditional BRK?
 BNE :NOcond ; if no
 PLA  ; skip LETTER6
 PLA  ; get Conditional Symbol
 STA BRKTGLOW,Y
 PLA  ; get Conditional Register
 STA BRKTGHI,Y
 BRA :GETtype

:NOcond PLA  ; SKIP LETTER6
 PLA  ; SKIP LETTER7
 PLA  ; skip LETTER8
:GETtype PLA  ; get BRK type
 STA BRKTYPE,Y

****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X
 INY
 STY POINT  ;UPDATE BRK STACK POINTER
 LDX XBUFF  ;RESTORE
 LDA #0  ;SET Z BIT
PUTDONE RTS

*-------------------------------------------------
* Display the registers

DISREG2 BIT STFLAG ; is STep mode on?
 BPL :doReg ; if no
 JMP DoDisAsm ; if yes skip register display

:doReg LDX #0
 LDY #0
NEXTREG JSR WRITREG  ;DISPLAY THE REGISTER LABEL
 LDA ACC,X
 CPX #$A  ;IF ONE OF 1ST 5 THEN
 BGE :ENDI
 PHA   ;SAVE
 INX
 LDA ACC,X  ;GET HI BYTE
 JSR TRANSFR2 ;PRINT REG. CONTENTS
 DFB PRBYTEC  ;CODE
 PLA   ;GET LO BYTE
:ENDI JSR TRANSFR2 ;PRINT REG. CONTENTS
 DFB PRBYTEC  ;CODE
 INX
 CPX #$E  ;UNTIL STATUS PRINTED
 BLT NEXTREG

* Display individual status flags
 LDA #"="
 JSR COUT2  ;PRINT "="
 LDA STATUS
 BIT EMULATE  ;WHICH MODE ?
 BMI :M6502  ;IF 6502
 LDX #8  ;USE FLAGS16
 BRA :NEXTF
:M6502 LDX #0
:NEXTF ASL   ;SHIFT N BIT INTO CARRY
 PHA   ;SAVE A
 BCS :FLGSET
 LDA #"-"
 BNE :NOTFLG
:FLGSET CMP $C800  ;DISABLE EXTRAM
 LDA FLAGS,X  ;LOAD LETTER OF FLAG FROM STRING NVEBDIZC
 CMP $CF00  ;ENABLE EXT RAM
:NOTFLG JSR COUT2  ;
 INX
 PLA   ;RESTORE A
 CPX #8  ;FINISHED YET?
 BLT :NEXTF  ;BLO IF NOT FINISHED
 BEQ :DOL  ;IF FINISHED
 CPX #16  ;FINISHED WITH FLAGS16
 BLT :NEXTF  ;BLO IF NOT FINISHED

* Print L flag. L=0 L/C not enabled, L=1 L/C bank1,
* L=2 L/C bank2

:DOL JSR WRITREG  ;PRINT "L="
 LDX #0
 BIT $C012  ;L/C OR ROM
 BPL LIS0  ;IF ROM
 BIT $C011  ;BANK1 OR 2
 BPL LIS1  ;IF BANK1
 INX   ;BANK2
LIS1 INX
LIS0 TXA
 JSR TRANSFR2 ;PRINT 0,1,OR 2
 DFB PRHEXC  ;CODE

* Print E flag
 JSR WRITREG  ;PRINT "E="
 LDA #"1"
 BIT EMULATE  ;816 MODE?
 BMI :NO  ;IF NO
 LDA #"0"
:NO JSR COUT2  ;DISPLAY 0 or 1

* Print I flag
 JSR WRITREG  ;PRINT "I="
 LDA #"0"
 LDX Iflag ; I flag set?
 Beq :noI  ;IF NO
 LDA #"1"
:noI JSR COUT2  ;DISPLAY 0 or 1

 JSR TRANSFR2 ;CARRIAGE RETURN
 DFB CROUTC  ;CODE

* List one line of disassembled code

DoDisAsm JSR TRANSFR2
 DFB DISASMC  ;CODE
 JSR TRANSFR2 ;CHECK FOR ACCESS TO NO ACCESS RANGE
 DFB CKACCESC ;code

* Update FLAG, MEM, EFF & STK windows
 JSR TRANSFR2 ;UPDATE FLAG,MEM,EFF,STACK WINDOWS
 DFB DISFMESC ;code
 JSR TRANSFR2
 DFB WINDDRC
 RTS

******************************
*  COMMAND MODE
******************************

COMDMO EQU *

*--------------------
* Set invisible mode

 LDY #0  ;init for write
 JSR DISMODE  ;display 1st mode choice
 LDA #"1"  ;determine current setting
 BIT INVISIBL
 BNE :INVMO
 LDA #"2"
:INVMO JSR GETCHOIC  ;get user's choice
 BEQ :CPUTYP  ;if <CR> entered

 STA INVISIBL  ;default to invisible on
 CMP #"2"  ;turn invisible off ?
 BNE :CPUTYP  ;if no
 STZ INVISIBL  ;invisible mode off

*---------------------
* Set CPU type

:CPUTYP JSR DISMODE  ;display mode choice
 LDA #"3"  ;determine current type
 BIT CMOSFLAG
 BVS :TYPE  ;65816
 BMI :TYPC02  ;65C02
 LDA #"1"  ;MUST BE 6502
 BRA :TYPE
:TYPC02 LDA #"2"
:TYPE JSR GETCHOIC ;get user's choice
 BEQ :TRCBRK  ;if <CR> entered

 LDX #%01000000 ;default to 65816 mode
 CMP #"1"  ;6502 type ?
 BNE :CKC02  ;if no
 LDX #0  ;set 6502 mode

:CKC02 CMP #"2"  ;65C02 type ?
 BNE :SETCPU  ;if no
 LDX #%10000000 ;set 65C02 mode

:SETCPU STX CMOSFLAG ;set new CPU type

:TRCBRK STZ RTBRKFLG ;do not trace user breaks

*----------------------
* Set I/O

:IOTYP JSR DISMODE  ;display mode choice
 LDA #"2"
 BIT IOMODE  ;0=NORMAL, BIT7 1=SERIAL, BIT6 1=SLOT1
 BMI :IOMOD  ;if serial
 LDA #"1"
 BVS :IOMOD  ;if printer
 LDA #"3"  ;if normal
:IOMOD JSR GETCHOIC ;get user's choice
 BEQ MODONE  ;if <CR> entered

 CMP #"3"  ;normal I/O ?
 BNE :CKSER  ;if no
 STZ IOMODE  ;screen output
 PEA COMDON-1 ;address of routine, display Main screen
 PEA S_COMDON ;segment of routine
 JMP JUMPSEG2 ;transfer segments

:CKSER CMP #"2" ;serial I/O ?
 BNE :CKPRINT ;if no
 LDA #$80 ;for IOMODE slot #2
 BRA :SETIO

:CKPRINT CMP #"1" ;output to slot #1 ?
 BNE MODONE ;if no
 LDA #$40 ;if slot #1
:SETIO STA IOMODE  ;$0=NORMAL, BIT7 1=SERIAL, BIT6 1=SLOT1
 JSR TRANSFR2 ;init slot
 DFB INITPASCC ;code
 PEA COMDOFF-1 ;address of routine, turn screen display off
 PEA S_COMDOFF ;segment of routine
 JMP JUMPSEG2 ;transfer segments

MODONE JSR TRANSFR2 ;display flag window
 DFB DISFLGWC ;code
 JSR TRANSFR2 ;set to DR window
 DFB WINDDRC
 BRA GETCOM2

*---------------------------*
*  Command ET
*---------------------------*

COMDET EQU *
 BEQ BPERR2 ;NO ADDRESS FOLLOWS

* Execute the code from address to address and display the
* number of clock cycles required.

 JSR CALCTIME
 BCS BPERR2 ;if the command was BAD
 JSR TRANSFR2 ;EXECUTE USERS PROGRAM
 DFB EXECUTEC ;code (no return)

*-------------------------------------------------
*  Bad Parameter error & do GET COMmand

BPERR2 LDA #BADPAR  ;BAD PARAMETER ERROR NUMBER
 JSR TRANSFR2 ;INDICATE ERROR
 DFB ERRBEEPC ;code
* fall thru to getcom2

*----------------------------------------
*  GETCOM2 - do <CR> & get user command

GETCOM2 PEA GETCOMCR-1 ;address of command
 PEA S_GETCOM ;segment of command
 JMP JUMPSEG2 ;goto command

*--------------------------------
* STA AT (PC,Y)

STAPCIY PHA
 LDA PBR
 STA DBRDDT
 memory16
 LDA PCLO
 STA LOWADD
 memory8
 PLA
 JSR TRANSFR2 ;STA (LOWADD,Y)
 DFB STAINDYC ;code
 RTS


*---------------------------------
* Write text to the display device
* The address of the text is on the stack
* Positive numbers are RLE compressed spaces
* At end of message C=1 and Acc = last character displayed

* THIS ROUTINE MUST BE ABOVE $CF00

WRITE2 STY YBUFF  ;SAVE
 LDY #0
WRITLOP2
 CMP $C800 ;disable DDT RAM
 LDA (3,S),Y ;get character to display
 CMP $CF00 ;enable DDT RAM
 INY  ;next character
 CMP #EOT ;finished?
 BEQ WRDONE2 ;if yes

WRITACC2 JSR COUT2 ;display character
 BRA WRITLOP2 ;loop until done

WRDONE2 MEMORY16
 PLA   ;get return address
 STA 1,S  ;free parameter space
 MEMORY8
 RTS

COUT2 JSR TRANSFR2 ;display on output device
 DFB COUTC  ;code
 RTS

*--------------------------------
* Display part of the mode choice menu

DISMODE PEA MSGMODE ;address of message
DOWRLOP2 JSR WRITLOP2 ;write from current Y pointer
 RTS

*-------------------------------------------------
* Display the register message pointed to by Y
* NOTE ALL REGISTER MESSAGES MUST BE CONSECUTIVE

WRITREG PEA MSGREGA ;address of message
 BRA DOWRLOP2

*---------------------
* Get user choice, display 'Enter <n> : '

GETCHOIC
 PHY   ;save mode menu pointer
 PHA   ;save default number
 PEA MSGENTER
 JSR WRITE2 ;display "Enter <"
 PLA  ;restore default
 PEA MSGENTER ;2nd part of message "> :"
 JSR WRITACC2 ;display ACC then rest of message

* Get mode input

 LDA #$A0  ;SPACE
 STA PROMPT  ;NEW PROMPT
 JSR TRANSFR2 ;GET INPUT
 DFB GETLNC  ;CODE
 BCS :ESC  ;if "esc" key
 INX
 LDY #00
 JSR TRANSFR2 ;GET 1ST CHAR
 DFB GETCHRC  ;CODE

 PLY   ;restore mode menu pointer
 CMP #CR  ;set z bit if <CR> entered
 RTS

* If "esc" key pressed
:ESC PLY   ;get Y off stack
 PLA
 PLA   ;pull return address off stack
 JMP MODONE  ;exit MOde command

*---------------------------------
* Move routines from ROM to RAM
* !!!!! NOTE Stack can NOT be in DDT RAM !!!!!

ROMTORAM LDA SLOTN0
 TAX   ;used in XFRIO
 ORA #$80
 PHA   ;push parameters for XFRIO
 LDA SLOTCN
 PHA

 CMP $C800  ;disable DDT RAM read
 JSR XFRIO  ;transfer routines to IO space
* DDT RAM enabled before returning
 PLA
 PLA   ;clean up stack

 RTS

*----------------------------------------
* Replace the breakpoint in the program with the original instruction.
* Remove the address from the breaks buffer, and reorganize the list.
* Enter with Y pointing to breakpoint.

REPLACE TYA
 TAX   ;POINTS AT BRK TO REPLACE
 LDY SLOTN0
 LDA POINT  ;BRK STACK POINTER
 PHA   ;PULLED IN SORTBRK
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,Y

 LDA BRKTYPE,X
 STA ACC+2  ;SAVE IN RAM6
 CMP #"I"  ;IMPLIED BRK ?
 BEQ SORTBRK  ;IF YES, STAY RAM6, ROM2
 LDA BRKDATA,X ;GET ORIGINAL DATA
 PHA
 LDA BRKPBR,X
 PHA
 LDA BRKHI,X
 PHA
 LDA BRKLOW,X
 PHA
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%00000010 ;RAM0 ROM2
 STA SEGMBASE,Y
 PLA
 STA LOWADD
 PLA
 STA HIADD
 PLA
 STA DBRDDT
 PLA   ;DATA
 LDY #0
 JSR TRANSFR2 ;REPLACE BRK WITH ORIG. DATA
 DFB STAINDYC ;code
 DEC REALBRK  ;DECREMENT REAL BRK COUNT
 LDY SLOTN0
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,Y

* Sort the BRK stack, shift up data to fill gap
SORTBRK STY ACC+1  ;SAVE SLOTN0
 PLA   ;GET BRK STACK POINTER
 STA ACC  ;SAVE IN SEG6

* Save the BRK info incase we are tracing this break
 LDA BRKPBR,X
 PHA
 LDA BRKHI,X
 PHA
 LDA BRKLOW,X
 PHA
 LDA BRKTGHI,X
 PHA
 LDA BRKTGLOW,X
 PHA
 LDA BRKPASHI,X
 PHA
 LDA BRKPASLO,X
 PHA
 LDA BRKDATA,X
 PHA

:NEXT TXA
 TAY   ;CURRENT BRK Y
 INX   ;NEXT BRK X
 CPX ACC  ;END OF DATA ON STACK ?
 BEQ :SORTEND ;IF YES
 LDA BRKTYPE,X ;SHIFT ALL DATA UP
 STA BRKTYPE,Y
 LDA BRKPBR,X
 STA BRKPBR,Y
 LDA BRKHI,X
 STA BRKHI,Y
 LDA BRKLOW,X
 STA BRKLOW,Y
 LDA BRKTGHI,X
 STA BRKTGHI,Y
 LDA BRKTGLOW,X
 STA BRKTGLOW,Y
 LDA BRKPASHI,X
 STA BRKPASHI,Y
 LDA BRKPASLO,X
 STA BRKPASLO,Y
 LDA BRKDATA,X
 STA BRKDATA,Y
 JMP :NEXT
:SORTEND

*-------------------------------------------------
* Put the info from the BRK just replaced above the current BRK stack point.
* To put the BRK back in simply increment the break stack pointer by 1.

 PLA
 STA BRKDATA,Y
 PLA
 STA BRKPASLO,Y
 PLA
 STA BRKPASHI,Y
 PLA
 STA BRKTGLOW,Y
 PLA
 STA BRKTGHI,Y
 PLA
 STA BRKLOW,Y
 PLA
 STA BRKHI,Y
 PLA
 STA BRKPBR,Y
 LDA ACC+2  ;BRKTYPE
 STA BRKTYPE,Y
 PHA

 LDX ACC+1  ;SLOTN0
****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************
 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X
 STY POINT  ;NEW BRK STACK POINTER
 PLA   ;TYPE OF BRK REMOVED
 RTS

***********************************
* Decrement TOGO if valid break
* TOGOFLG = 0 if TOGO = 0
***********************************

* Use current PC

DECTGPC JSR PC2LETR  ;LOAD LETTER 3,2,1 WITH PC

DECTOGO LDA #0  ;DEC TOGO FLAG
 BEQ VALID2

***********************************
* Check if address is valid breakpoint on list.
* Returns with:
*   N=1 IF INVALID
*   Z=1 & V=0 IF VALID and Real BRK
*   Z=0 & V=0 if VALID and Implied BRK
*   Z=1 & V=1 if VALID and Conditional BRK
* LETTER 3,2,1 must contain the instruction address
***********************************

* Use current PC

VALIDPC JSR PC2LETR  ;LOAD LETTER 3,2,1 WITH PC

VALIDAD LDA #$80  ;DON'T DEC TOGO
VALID2 PHA   ;SAVE TOGO FLAG
 LDA #$80
 STA TOGOFLG  ;RESET TOGO FLAG
 STY YBUFF  ;SAVE Y
 STX XBUFF  ;SAVE X
 LDY POINT  ;GET BREAKS POINTER
 DEY   ;ARE THERE ANY BREAKS ?
 BPL :BRKS  ;IF YES
 PLA   ;CLEAN UP STACK
 TYA   ;SET STATUS FLAGS
 RTS   ;IF NO

:BRKS INY
 LDA LETTER3  ;PBR OF BRK ADDRESS
 PHA
 LDA LETTER2  ;HI BYTE
 PHA
 LDA LETTER1  ;LOW BYTE
 PHA
 LDX SLOTN0

****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************

 LDA #%01100010 ;RAM6, ROM2
 STA SEGMBASE,X
 PLA
 STA ACC+2  ;STORE IN RAM SEG6
 PLA
 STA ACC+1
 PLA
 STA ACC
 PLA   ;GET DEC TOGO FLAG
 STA ACC+3
 LDA #$80
 STA ACC+4  ;USE THIS AS TOGOFLG
 CLV  ; preset V=0 to non conditional break
:LOOPLO DEY
 BMI :LEAVE  ;INVALID N=1
 LDA ACC+2  ;LOW BYTE
 CMP BRKLOW,Y ;MATCH ?
 BNE :LOOPLO  ;IF NO

 LDA ACC+1  ;HI BYTE
 CMP BRKHI,Y  ;HI BYTES MATCH ?
 BNE :LOOPLO  ;IF NO

 LDA ACC  ;PBR BYTE
 CMP BRKPBR,Y ;MATCH ?
 BNE :LOOPLO  ;IF NO, IF VALID FALL THROUGH

 LDA #"C"
 CMP BRKTYPE,Y ; was this a conditional break?
 BEQ :CONDbrk ; if yes

 LDA ACC+3  ;DEC TOGO ?
 BMI :CKREAL  ;IF NO

* Decrement TOGO count

 SEC
 LDA BRKTGLOW,Y
 SBC #1
 STA BRKTGLOW,Y
 LDA BRKTGHI,Y
 SBC #0
 STA BRKTGHI,Y

* Does TOGO = 0 ?
 BNE :CKREAL  ;TOGO NOT 0
 LDA BRKTGLOW,Y
 BNE :CKREAL  ;TOGO NOT 0

* ACC = 0
 STA ACC+4  ;TOGO = 0

 LDA BRKPASHI,Y
 STA BRKTGHI,Y ;RESET TOGO
 LDA BRKPASLO,Y
 STA BRKTGLOW,Y


:CKREAL LDA #"R"
 CLV  ; set V=0 for non conditional break
 CMP BRKTYPE,Y ;Z=1 IF REAL BRK
 BRA :LEAVE

* Conditional break
:CONDBRK LDA BRKTGHI,Y ; register offset of conditional break
 PHA
 LDA BRKTGLOW,Y ; condition offset of conditional break
 PHA
 LDA BRKPASHI,Y ; hi byte of conditional compare
 PHA
 LDA BRKPASLO,Y ; low byte of conditional compare
 PHA
 SEP #$40 ; set V=1 to indicate conditional break

:LEAVE PHP   ;SAVE FLAGS
 LDA ACC+4  ;TOGO FLAG
 PHA

****************************************
* !!! ALERT !!! SEGMENT DEPENDENT CODE *
****************************************

 LDA #%00000010 ;RAM0, ROM2
 STA SEGMBASE,X

 PLA   ;GET TOGO FLAG
 STA TOGOFLG  ;SET FLAG
 LDX XBUFF  ;RESTORE X
 PLP   ;RESTORE FLAGS
* ON VALID RETURN Y IS POINTING TO ADDRESS IN BREAKS BUFFER.
 BVS :CHKCOND ; if a conditional break
 RTS

* Check the conditions of the break
:CHKCOND MEMORY16
 PLA ;get conditional compare value
 STA TEMP
 PLA  ;get register offset, condition offset
 STA TEMP+2
 LDX TEMP+3 ;register offset
 AND #$00FF
 CLC
 ADC #CONDBRKS ;address of proper branch sequence
 STA TEMP+2
 MX8
 CPX #$A ;byte or word compare?
 BGE :BYTECMP ;if byte
 MEMORY16 ;do word compare
:BYTECMP LDA ACC,X ;get proper register value
 CMP TEMP ;compare to conditional value
 MEMORY8
 SEP #$40 ; force V=1 to indicate Conditional break
 JMP (TEMP+2) ;go to proper branch sequence

 mx %11

CONDBRKS
condEQ beq dobrk
 bra nobrk

condLT blt dobrk
 bra nobrk

condGE bge dobrk
 bra nobrk

condNE bne dobrk
 bra nobrk

condGT blt nobrk
 bne dobrk
 bra nobrk

condLE blt dobrk
 beq dobrk ;falls through to nobrk

nobrk lda #$40
 sta TOGOflg ;set flag to continue program
 lda #0 ;force N=0 & Z=1 to indicate valid BRK
 rts

dobrk lda #0 ;force N=0 & Z=1 to indicate valid BRK
 sta TOGOflg ;set flag to halt program
 rts


* Put current PC into LETTER 3,2,1

PC2LETR LDA PBR
 STA LETTER3
 LDA PCHI
 STA LETTER2
 LDA PCLO
 STA LETTER1
 RTS

*-------------------------------------------------
* Setup VIA for Trace if enabled

TRSETVIA JSR SAVEVIAR ;save current VIA registers
 LDA STACK
 STA VIAORA ;low byte of compare
 LDA STACK+1
 STA VIAORB ;hi byte of compare
 LDA #%10010000
 TSB IERBUFF ;enable hardware break for Trace
 JMP SETETVEC ;set vector to goto after NMI, share ET vector

*--------------- CALCTIME --------------*

CALCTIME JSR SAVEVIAR ;save current VIA registers
 JSR TRANSFR2 ;read in 2 addresses
 DFB CHKREADC ;code
 BCS ETERR ;IF ERROR
 BIT ADDRS2F ;2 ADDRESSES ENTERED ?
 BPL ETERR ;IF NO
 STA PCLO ;LOW BYTE OF 1ST ADDRESS
 LDA LETTER2 ;HI BYTE OF 1ST ADDRESS
 STA PCHI ;REPLACE PC
 LDA LETTER4 ;LOW BYTE OF 2ND ADDRESS
 STA VIAORA
 LDA LETTER5 ;HI BYTE OF 2ND ADDRESS
 STA VIAORB ;REPLACE HARD BREAK
 LDA #%10010000
 STA IERBUFF ;ENABLE HARD BREAK
 STA ETFLAG ;SET FLAG FOR NMIVEC ROUTINE

 LDA VIAACR
 AND #%11011111 ;SET T2 FOR TIMED INTERRUPT MODE
 STA VIAACR

*********** COUNTER PRESET ************
* Bigger number makes ET smaller

 CLC  ; if E=0 add 1
 LDA #$82 ; default to fast count
 BIT $C036 ; fast mode?
 BMI :CHECKE ; if yes
 SEC  ; if E=0 add 2
 LDA #$8B ; slow count

:CHECKE BIT EMULATE ; native mode ?
 BMI :EMULCNT ; if no
 ADC #1 ; add 1+C if native mode

:EMULCNT LDX #$C7
 CPX SLOTCN ;are we in slot #7?
 BNE :NOT7 ;if not
 INC  ;if yes allow an extra cycle
:NOT7 STA VIAT2CL ;COUNTER PRESET
SETETVEC LDA #ETVECTOR
 STA ENABLTVC
 LDA #>ETVECTOR ;SET UP NMI VECTOR
 STA ENABLTVC+1
 CLC
ETRTS RTS

ETERR JSR ETRESTOR ;RESTORE PC & VIA
 SEC
 RTS ;USE CARRY BIT AS AN ERROR FLAG

SAVEVIAR PHA ;SAVE CHARACTER
 MEMORY16
 LDA PCLO
 STA ETPCLO ;SAVE PC
 MEMORY8
 LDA IERBUFF
 STA ETIERSAV ;SAVE VIAIER
 LDA VIAORA
 STA ETORASAV ;SAVE ORA & ORB
 LDA VIAORB
 STA ETORBSAV
 PLA ;GET CHARACTER
 RTS

*-------------------------------------------------
* Continuation of ETvector
* "ET" & "Trace" both come here

ETVCONT BIT TRACFLAG ;was NMI caused by Trace?
 BMI TRRESTOR ;if yes
 LDA VIAT2CH ;GET COUNTER VALUE
 EOR #$FF ;ONES COMPLIMENT
 PHA
 LDA VIAT2CL
 EOR #$FF ;ONES COMPLIMENT
 PHA ;SAVE

* Display "CLOCK CYCLES = $"
 PEA MSGET ;message location
 JSR WRITE2 ;display it

 PLA
 TAX
 PLA
 JSR TRANSFR2 ;DISPLAY 4 DIGIT HEX COUNTER VALUE
 DFB PRNTAXC ;CODE

* display "(x ~2.6)" if fast mode
 BIT $C036
 BPL :SLOW
 PEA FASTET ;message location
 JSR WRITE2 ;display it

:SLOW JSR ETRESTOR ;RESTORE PC & VIA
 LDA #0
 STA ETFLAG ;CLEAR FLAG
 RTS ;RETURN TO GETCOMCR

* Subroutines for CALCTIME

* Restore PC & VIA

ETRESTOR LDA ETPCLO
 STA PCLO
 LDA ETPCHI
 STA PCHI
TRRESTOR LDA ETORBSAV
 STA VIAORB
 LDA ETORASAV
 STA VIAORA
 LDA ETIERSAV
 STA IERBUFF ;RESTORE IERBUFF
 RTS

*----------------------------------------
***** THIS SEGMENTS GLOBAL SUBROUTINES *****

SUBTABL2

PUTBREAKC EQU *-SUBTABL2*4+2+$100
 DA PUTBREAK-1

UPDATEC EQU *-SUBTABL2*4+2+$100
 DA UPDATE-1

DISREG2C EQU *-SUBTABL2*4+2+$100
 DA DISREG2-1

ROMTORAMC EQU *-SUBTABL2*4+2+$100
 DA ROMTORAM-1

DECTGPCC EQU *-SUBTABL2*4+2+$100
 DA DECTGPC-1

DECTOGOC EQU *-SUBTABL2*4+2+$100
 DA DECTOGO-1

VALIDPCC EQU *-SUBTABL2*4+2+$100
 DA VALIDPC-1

VALIDADC EQU *-SUBTABL2*4+2+$100
 DA VALIDAD-1

REPLACEC EQU *-SUBTABL2*4+2+$100
 DA REPLACE-1

STAPCIYC EQU *-SUBTABL2*4+2+$100
 DA STAPCIY-1

TRSETVIAC EQU *-SUBTABL2*4+2+$100
 DA TRSETVIA-1

ETVCONTC EQU *-SUBTABL2*4+2+$100
 DA ETVCONT-1

*****************************************
*  SEGMENT CROSSOVER AREA  *
*****************************************

 LST ON
S2END = $E0CF91-*
 do nolist
 LST OFF
 fin
 ERR *-1/$E0CF91
 DS $E0CF91-*,$FF

******** SAVE THE ACC, X, Y AND P REGISTERS *******
* Returns with MX = 11, saves registers

SAVEAXP2
 PHP   ;SAVE STATUS
 MX16
 STX XSAVESEG ;save 16 bits
 STY YSAVESEG ;save 16 bits
 STA ASAVESEG ;save 16 bits
 MX8
 PLA   ;GET STATUS
 STA PSAVESEG ;SAVE
 RTS

****** RESTORE THE ACC, X, Y AND P REGISTERS ******
* restores registers

RESTAXP2
 MEMORY8
 LDA PSAVESEG
 PHA
 MX16
 LDX XSAVESEG
 LDY YSAVESEG
 LDA ASAVESEG
 PLP
 RTS
 MX %11

*----------------------------------------
* Do a direct transfer to other segments

JUMPSEG2
 JSR SAVEAXP2
 LDY SLOTN0
 PLA   ;pull junk byte from dest. seg
 PLA   ;get destination segment
 STA SEGMBASE,Y ;the next inst' will be in new seg
 JSR RESTAXP2 ;restore after xfer from other seg
SEG2RTS RTS   ;pull destination address from stack

* TRANSFER TO OTHER SEGMENTS

TRANSFR2

 JSR SAVEAXP2
 MEMORY16
 PLA   ;get return address from stack
 INC   ;inc to point at code byte & for RTS
 PHA
 MEMORY8
 LDA #2  ;CURRENT SEG #
 PHA
 LDY #0
 LDA (2,S),Y  ;GET CODE BYTE
 PHA   ;SAVE CODE
 AND #$07  ;STRIP ALL BUT SEG #
 LDY SLOTN0
 STA SEGMBASE,Y ;NEXT INSTR. RUN FROM NEW SEGMENT
* NEW SEGMENT
 PLA   ;GET CODE
 PEA RETURN2  ;where to return to
 AND #$F8  ;STIP OFF SEG# LEAVING SUB #
 LSR
 LSR   ;LEAVE SUB# MULTIPLIED BY 2
* GET ADDRESS OF SUB FROM SUBTABL & PUSH ON STACK
 TAY
 MEMORY16
 LDA SUBTABL2,Y
 PHA
 BRA RESTAXP2 ;RESTORE REGISTERS, RTS TO SUBROUTINE
 MX %11

* RETURN HERE FROM SUBROUTINE

RETURN2 EQU *-1
 JSR SAVEAXP2
 PLA   ;SEG # TO RETURN TO
 LDY SLOTN0
 STA SEGMBASE,Y ;RETURN TO SEGMENT
 BRA RESTAXP2

 DS \,$FF  ;PUT OBJECT AT NEXT PAGE
